import axios from 'axios'
import { isFunction } from './utils/index'
import { cloneDeep } from 'lodash'

export class JAxios {
	#axiosInstance
	#options

	constructor(options) {
		this.#options = options
		this.#axiosInstance = axios.create(options)
		this.setupInterceptors()
	}

	getTransform() {
		const { transform } = this.#options
		return transform
	}

	setupInterceptors() {
		const transform = this.getTransform()
		if (!transform) {
			return
		}
		const { requestInterceptors, requestInterceptorsCatch, responseInterceptors, responseInterceptorsCatch } = transform

		this.#axiosInstance.interceptors.request.use(config => {
			if (requestInterceptors && isFunction(requestInterceptors)) {
				config = requestInterceptors(config, this.#options)
			}
			return config
		}, undefined)

		requestInterceptorsCatch &&
			isFunction(requestInterceptorsCatch) &&
			this.#axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch)

		this.#axiosInstance.interceptors.response.use(res => {
			if (responseInterceptors && isFunction(responseInterceptors)) {
				res = responseInterceptors(res)
			}
			return res
		}, undefined)

		responseInterceptorsCatch &&
			isFunction(responseInterceptorsCatch) &&
			this.#axiosInstance.interceptors.response.use(undefined, responseInterceptorsCatch)
	}

	get(config, options) {
		return this.request({ ...config, method: 'GET' }, options)
	}

	post(config, options) {
		return this.request({ ...config, method: 'POST' }, options)
	}

	put(config, options) {
		return this.request({ ...config, method: 'PUT' }, options)
	}

	delete(config, options) {
		return this.request({ ...config, method: 'DELETE' }, options)
	}

	request(config, options) {
		let conf = cloneDeep(config)
		const { requestOptions } = this.#options
		conf.requestOptions = Object.assign({}, requestOptions, options)
		return new Promise((resolve, reject) => {
			this.#axiosInstance
				.request(conf)
				.then(res => {
					resolve(res)
				})
				.catch(e => {
					reject(e)
				})
		})
	}
}
